package com.perfree.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.github.pagehelper.PageInfo;
import com.perfree.common.AjaxResult;
import com.perfree.common.DateUtil;
import com.perfree.entity.FileResult;
import com.perfree.entity.Peers;
import com.perfree.entity.Share;
import com.perfree.entity.ShareDTO;
import com.perfree.service.FileService;
import com.perfree.service.ShareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author Perfree
 * @Date 10:58 2019/5/11
 * 文件列表controller
 */
@Controller
public class FileController extends BaseController {

    @Autowired
    private FileService fileService;

    @Autowired
    private ShareService shareService;

    /**
     * 文件列表
     *
     * @return String
     */
    @RequestMapping("/file")
    public String index() {
        return "file/file";
    }

    @RequestMapping("/file/list/share")
    public String listShare() {
        return "file/list-share";
    }

    @RequestMapping("/file/list/share/table")
    @ResponseBody
    public Map<Object, Object> listShareTable(@RequestParam(defaultValue = "1") int page,
                              @RequestParam(defaultValue = "30") int limit,
                              HttpServletRequest request) {
        List<Share> list = shareService.getShareTable(page, limit);
        String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +
                request.getContextPath() + "/share/";
        List<ShareDTO> result = new ArrayList<>();
        for (Share share : list) {
            ShareDTO shareDTO = new ShareDTO();
            shareDTO.setUrl(url + share.getPathMd5());
            shareDTO.setUsername(getUser().getName());
            shareDTO.setName(share.getName());
            shareDTO.setPassword(share.getPassword());
            shareDTO.setCreateTime(share.getCreateTime());
            shareDTO.setId(share.getId());
            shareDTO.setSize(StrUtil.equals("0", share.getSize()) ? "-" : share.getSize());
            result.add(shareDTO);
        }
        PageInfo<ShareDTO> pageInfo = new PageInfo<>(result);
        Map<Object, Object> maps = new HashMap<>();
        maps.put("code", 0);
        maps.put("msg", "OK");
        maps.put("data", result);
        maps.put("count", pageInfo.getTotal());
        return maps;
    }
    /**
     * 文件列表
     *
     * @return String
     */
    @RequestMapping("/share/{md5}")
    public String share(@PathVariable("md5") String md5, Model model) {
        model.addAttribute("md5", md5);
        return "file/extractLogin";
    }

    /**
     * 文件列表
     *
     * @return String
     */
    @PostMapping("/share/file/login")
    @ResponseBody
    public AjaxResult shareLogin(String md5, String extract, Model model, HttpServletRequest request) {
        model.addAttribute("md5", md5);
        if(shareService.validateShare(md5, extract)) {
            request.getSession().setAttribute("isValidate", md5);
            return new AjaxResult(AjaxResult.AJAX_SUCCESS, "OK");
        } else {
            return new AjaxResult(401, "访问密码错误");
        }
    }

    @GetMapping("/share/page/{md5}")
    public String shareLogin(@PathVariable String md5, HttpServletRequest request) {
        Object isValidate = request.getSession().getAttribute("isValidate");
        request.setAttribute("md5", md5);
        if(isValidate != null && StrUtil.equals(md5, String.valueOf(isValidate))) {
            return "file/share";
        }
        return "file/extractLogin";
    }

    @PostMapping("/share/obtain/file")
    @ResponseBody
    public AjaxResult getFiles(HttpServletRequest request) {
        String md5 = (String)request.getSession().getAttribute("isValidate");
        if(StrUtil.isBlank(md5)) {
            return new AjaxResult(AjaxResult.AJAX_ERROR, "无权获取");
        }
        Share share = shareService.getShareByMd5(md5);
        Peers peers = shareService.getPeersByUserId(share.getUserId());

        request.getSession().setAttribute("sharepeers", peers);

        ArrayList<FileResult> list = new ArrayList<>();
        FileResult fileResult = new FileResult();
        fileResult.setMd5(share.getPathMd5());
        fileResult.setPath(share.getPath());
        fileResult.setName(share.getName());
        fileResult.setSize(share.getSize());
        fileResult.setIs_dir(share.getIsDir() == 1);
        fileResult.setPeerAddr(buildShowUrl(peers));
        fileResult.setMTime(DateUtil.getFormatDate(share.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
        list.add(fileResult);
        return new AjaxResult(AjaxResult.AJAX_SUCCESS, list);
    }

    /**
     * 获取一级目录
     *
     * @return AjaxResult
     */
    @RequestMapping("/share/file/getDirFile")
    @ResponseBody
    public AjaxResult getShareDirFile(String dir, HttpServletRequest request) {
        Peers peers = (Peers)request.getSession().getAttribute("sharepeers");
        if(peers == null) {
            return new AjaxResult(AjaxResult.AJAX_ERROR, "无权获取");
        }
        return new AjaxResult(AjaxResult.AJAX_SUCCESS, fileService.getDirFile(buildShowUrl(peers),buildPeersUrl(peers), dir));
    }

    /**
     * 文件信息
     *
     * @param md5
     * @return AjaxResult
     */
    @RequestMapping("/share/file/details")
    @ResponseBody
    public AjaxResult shareDetails(String md5, HttpServletRequest request) {
        Peers peers = (Peers)request.getSession().getAttribute("sharepeers");
        return fileService.details(buildPeersUrl(peers), md5);
    }

    @RequestMapping("/share/file/downloadFile")
    @ResponseBody
    public void downloadShareFile(String path, String name, HttpServletRequest request, HttpServletResponse response) {
        downloadFile(path, name, request, response);
    }

    /**
     * 目录或者文件共享
     *
     * @return AjaxResult
     */
    @PostMapping("/file/share/gen")
    @ResponseBody
    public AjaxResult shareGen(Share share, HttpServletRequest request) {
        share.setUserId(getUser().getId());// 记录共享人是谁
        share.setPeerId(getUser().getPeersId());
        Share share1 = shareService.saveShareInfo(share);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("url", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +
                request.getContextPath() + "/share/" + share1.getPathMd5());
        jsonObject.put("password", share1.getPassword());
        return new AjaxResult(AjaxResult.AJAX_SUCCESS,jsonObject);
    }

    /**
     * 获取一级目录
     *
     * @return AjaxResult
     */
    @RequestMapping("/file/getParentFile")
    @ResponseBody
    public AjaxResult getParentFile() {
        return new AjaxResult(AjaxResult.AJAX_SUCCESS, fileService.getParentFile(getPeersGroupName(),getPeersUrl()));
    }


    /**
     * 指定目录获取
     *
     * @param dir
     * @return AjaxResult
     */
    @RequestMapping("/file/getDirFile")
    @ResponseBody
    public AjaxResult getDirFile(String dir) {
        return new AjaxResult(AjaxResult.AJAX_SUCCESS, fileService.getDirFile(getShowUrl(),getPeersUrl(), dir));
    }

    /**
     * 删除文件
     *
     * @param md5
     * @return AjaxResult
     */
    @RequestMapping("/file/deleteFile")
    @ResponseBody
    public AjaxResult deleteFile(String md5) {
        if (fileService.deleteFile(getPeersUrl(),md5)) {
            return new AjaxResult(AjaxResult.AJAX_SUCCESS);
        }
        return new AjaxResult(AjaxResult.AJAX_ERROR, "删除失败");
    }

    /**
     * 文件信息
     *
     * @param md5
     * @return AjaxResult
     */
    @RequestMapping("/file/details")
    @ResponseBody
    public AjaxResult details(String md5) {
        return fileService.details(getPeersUrl(),md5);
    }

    /**
     * 下载文件
     * @param path
     * @param name
     * @param response
     */
    @RequestMapping("/file/downloadFile")
    @ResponseBody
    public void downloadFile(String path, String name, HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Content-Disposition", "attachment;filename=" + name);
        response.setContentType("application/octet-stream");
        Peers p = getPeers();
        if(p == null)
            p = (Peers)request.getSession().getAttribute("sharepeers");
        String peersUrl = p.getServerAddress();
        if(StrUtil.isNotBlank(p.getGroupName())){
            peersUrl += "/"+ p.getGroupName();
        }else {
            peersUrl += "/group1";
        }
        BufferedInputStream in = null;
        try {
            URL url = new URL(peersUrl+"/"+path+"/"+name);
            in = new BufferedInputStream(url.openStream());
            response.reset();
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
            // 将网络输入流转换为输出流
            int i;
            while ((i = in.read()) != -1) {
                response.getOutputStream().write(i);
            }
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
               if (in != null){
                   in.close();
               }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
